package com.vb.scrum.client;

import java.util.ArrayList;
import java.util.HashMap;

import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.allen_sauer.gwt.dnd.client.drop.AbsolutePositionDropController;
import com.allen_sauer.gwt.dnd.client.drop.SimpleDropController;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.DecoratedPopupPanel;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.vb.scrum.client.widget.TaskSticky;
import com.vb.scrum.client.widget.UserStorySticky;

public class ScrumApplication {
	
	//These lists represent the states and substates of app, for first release are hardcoded and will be a custom feature next release
	private static final ArrayList<String> appStates=new ArrayList<String>();
	private static final ArrayList<String> appSubStates=new ArrayList<String>();
	private TabSelectionHandler tabSelectHandle=new TabSelectionHandler();
	private HashMap<Integer, ArrayList<AbsolutePanel>> panelMap=new HashMap<Integer, ArrayList<AbsolutePanel>>();
	private int selectedTab;
	private DecoratedTabPanel tabPanel;
	private VerticalPanel topPanel;
	private PickupDragController dragControl;	

	private Utility util;
	
	static
	{
	appStates.add("Plan it");
	appStates.add("Build it");
	appStates.add("Check it");
	appSubStates.add("Ready");
	appSubStates.add("Working");
	appSubStates.add("Done");	
	}
	
	public int getSelectedTab() {
		return selectedTab;
	}
	public void setSelectedTab(int selectedTab) {
		this.selectedTab = selectedTab;
	}
	public Widget onInitialize(){
		//TODO The size of Main panel has to be set based on scren size, for now its a fixes size
		util=new Utility();
		topPanel=new VerticalPanel();					
		topPanel.add(this.getTopPanel());		
		addMainPanel();
		return topPanel;
	}

	private void addMainPanel(){		
		tabPanel = new DecoratedTabPanel ();		
		tabPanel.addSelectionHandler(tabSelectHandle);		
	    tabPanel.setAnimationEnabled(true);
	    tabPanel.setSize(util.getMainPanelWidth(), util.getMainPanelHeight());
	    dragControl=new PickupDragController(RootPanel.get(), false);
	 	for(String stateVal: appStates){
	 		Widget tabWidget=getTab(stateVal);
	    	tabPanel.add(getTableForTab(tabPanel.getTabBar().getTabCount()),tabWidget);
	    	int numT=tabPanel.getTabBar().getTabCount();
		    TabSelectingDropController tabDrop=new TabSelectingDropController(tabWidget,tabPanel,numT-1);
		    dragControl.registerDropController(tabDrop);
	    }	 	
	    tabPanel.selectTab(0);
	    topPanel.add(tabPanel);	    
	}

	private Widget getTab(String stateVal){
		Button tabButton = new Button(stateVal);
		tabButton.setStyleName("scrum-tabPanel-tab");		
		return tabButton;
	}
	
	/*
	 * Provides the content for each state (Tab) and registers the panels added to a app level data structure
	 */
	private Widget getTableForTab(int stateVal){
	    HorizontalPanel hPanel=new HorizontalPanel();
	    AbsolutePanel absPanel=new AbsolutePanel();
		AbsolutePanel absPanel1=new AbsolutePanel();
	    absPanel1.setSize(util.getSubStatePanel1_width(), util.getSubStatePanelHeight());
	    absPanel1.setStyleName("absPanel1");
	    absPanel1.add(getTableTitles("Ready"));
	    AbsolutePositionDropController dropCon1=new AbsolutePositionDropController(absPanel1);
	    dragControl.registerDropController(dropCon1);
	    
	    AbsolutePanel absPanel2=new AbsolutePanel();
	    absPanel2.setSize(util.getSubStatePanel2_width(), util.getSubStatePanelHeight());
	    absPanel2.setStyleName("absPanel2");
	    absPanel2.add(getTableTitles("Working"));
	    AbsolutePositionDropController dropCon2=new AbsolutePositionDropController(absPanel2);
	    dragControl.registerDropController(dropCon2);
	    
	    
	    AbsolutePanel absPanel3=new AbsolutePanel();
	    absPanel3.setSize(util.getSubStatePanel3_width(), util.getSubStatePanelHeight());
	    absPanel3.setStyleName("absPanel3");
	    absPanel3.add(getTableTitles("Done"));
	    AbsolutePositionDropController dropCon3=new AbsolutePositionDropController(absPanel3);
	    dragControl.registerDropController(dropCon3);
	    
	    hPanel.add(absPanel1);
	    hPanel.add(absPanel2);
	    hPanel.add(absPanel3);
	    ArrayList<AbsolutePanel> panelList=new ArrayList<AbsolutePanel>();
	    panelList.add(absPanel1);
	    panelList.add(absPanel2);
	    panelList.add(absPanel3);
	    panelMap.put(stateVal, panelList);
	    absPanel.add(hPanel);
	    return absPanel;
	}
	
	/*
	 * User passes the description of the Label and a label is returned with other formattng done
	 * Used for column names of the Table inside the tab
	 */
	private Widget getTableTitles(String labelString) {
		Label lbl=new Label(labelString);
		//lbl.setDirection("");
		lbl.setStyleName("scrum-table-title");		
		return lbl;
		
	}
	
	public Widget getTopPanel(){
		FlowPanel hPanel = new FlowPanel();
		// FlowPanel hPanel;
		hPanel.setStyleName("hpanel-top");
		hPanel.setSize(util.getTopPanelWidth(), util.getTopPanelHeight());
		final DecoratedPopupPanel simplePopup = new DecoratedPopupPanel(true);
		simplePopup.setWidth("200px");
		simplePopup
				.setWidget(new Label(
						"SCRUM-WALL application is ideated and built by vrbiyani@gmail.com. "
								+ "You are welcome to suggest changes and to collaborate to enhance further to suit for your needs"));
		Button abtButton = new Button("About", new ClickHandler() {
			public void onClick(ClickEvent event) {
				Widget source = (Widget) event.getSource();
				int left = source.getAbsoluteLeft() - 150;
				// TODO The position is fixed to a value 150 left of button,
				// might hamper
				int top = source.getAbsoluteTop() + 10;
				simplePopup.setPopupPosition(left, top);
				simplePopup.show();
			}
		});
		Button storyButton = new Button("+ Story", new StoryCreator());
		Button taskButton = new Button("+ Task", new TaskCreator());
		// Styles defined in Scrum.css
		storyButton.setStyleName("scrum-story-button");
		taskButton.setStyleName("scrum-task-button");
		abtButton.setStyleName("scrum-abt-button");
		hPanel.add(storyButton);
		hPanel.add(taskButton);
		hPanel.add(abtButton);
		return hPanel;
}
	/*
	 * SECTION: Various event handlers and listeners implementation 
	 * */
	
/*This method sets a property for this object when selected tabs is changed, which is used by other methods
 * */	
private class TabSelectionHandler implements SelectionHandler<Integer>{
	@Override
	public void onSelection(SelectionEvent<Integer> event) {
		// TODO Auto-generated method stub
		Integer select=event.getSelectedItem();		
		setSelectedTab(select.intValue());
	}
}	

private class StoryCreator implements ClickHandler {
	@Override
	public void onClick(ClickEvent event) {		
		AbsolutePanel absPanel=(AbsolutePanel)panelMap.get(getSelectedTab()).get(0);
		UserStorySticky story =new UserStorySticky();
		Widget storySticky=story.onInitialize();
		absPanel.add(storySticky);
		dragControl.makeDraggable(storySticky, story.getDragger());
	}	
}

private class TaskCreator implements ClickHandler{
	@Override
	public void onClick(ClickEvent event) {
		AbsolutePanel absPanel=(AbsolutePanel)panelMap.get(getSelectedTab()).get(0);
		TaskSticky task =new TaskSticky();	
		Widget taskSticky=task.onInitialize();
		absPanel.add(taskSticky);
		dragControl.makeDraggable(taskSticky, task.getDragger());
	}
}
	
}
